package com.zhaoqi.hr.service;

import com.zhaoqi.hr.dto.request.DocumentAuditRequest;
import com.zhaoqi.hr.dto.request.DocumentUploadRequest;
import com.zhaoqi.hr.dto.response.DocumentResponse;
import com.zhaoqi.hr.entity.User;
import com.zhaoqi.hr.entity.UserDocument;
import com.zhaoqi.hr.repository.UserDocumentRepository;
import com.zhaoqi.hr.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 文档服务
 */
@Service
public class DocumentService {

    private static final Logger log = LoggerFactory.getLogger(DocumentService.class);

    @Autowired
    private UserDocumentRepository documentRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OssService ossService;

    @Value("${file.upload.max-size}")
    private long maxFileSize;

    /**
     * 上传文档
     */
    @Transactional
    public DocumentResponse uploadDocument(Long userId, DocumentUploadRequest request, MultipartFile file) {
        log.info("用户 {} 上传文档: {}", userId, request.getDocumentName());

        // 验证用户存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        // 验证文件
        validateFile(file);

        // 上传文件到OSS
        String fileUrl = ossService.uploadUserDocument(file, userId);

        // 创建文档记录
        UserDocument document = new UserDocument();
        document.setUserId(userId);
        document.setDocumentType(request.getDocumentType());
        document.setDocumentName(request.getDocumentName());
        document.setDescription(request.getDescription());
        document.setDocumentNumber(request.getDocumentNumber());
        document.setFilePath(fileUrl);
        document.setFileSize(file.getSize());
        document.setAuditStatus(UserDocument.AuditStatus.PENDING);
        document.setCreatedAt(LocalDateTime.now());
        document.setUpdatedAt(LocalDateTime.now());

        document = documentRepository.save(document);

        log.info("文档上传成功，ID: {}", document.getId());
        return convertToResponse(document);
    }

    /**
     * 获取用户文档列表
     */
    public List<DocumentResponse> getUserDocuments(Long userId) {
        List<UserDocument> documents = documentRepository.findByUserIdOrderByCreatedAtDesc(userId);
        return documents.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * 获取待审核文档列表（管理员用）
     */
    public Page<DocumentResponse> getPendingDocuments(Pageable pageable) {
        Page<UserDocument> documents = documentRepository.findByAuditStatusOrderByCreatedAtAsc(
                UserDocument.AuditStatus.PENDING, pageable);
        return documents.map(this::convertToResponse);
    }

    /**
     * 审核文档
     */
    @Transactional
    public DocumentResponse auditDocument(Long auditUserId, DocumentAuditRequest request) {
        log.info("管理员 {} 审核文档 {}", auditUserId, request.getDocumentId());

        UserDocument document = documentRepository.findById(request.getDocumentId())
                .orElseThrow(() -> new RuntimeException("文档不存在"));

        if (document.getAuditStatus() != UserDocument.AuditStatus.PENDING) {
            throw new RuntimeException("文档已审核，无法重复审核");
        }

        document.setAuditStatus(request.getAuditStatus());
        document.setAuditComment(request.getAuditComment());
        document.setAuditUserId(auditUserId);
        document.setAuditTime(LocalDateTime.now());
        document.setUpdatedAt(LocalDateTime.now());

        document = documentRepository.save(document);

        log.info("文档审核完成，状态: {}", request.getAuditStatus());
        return convertToResponse(document);
    }

    /**
     * 获取文档详情
     */
    public DocumentResponse getDocumentById(Long documentId) {
        UserDocument document = documentRepository.findById(documentId)
                .orElseThrow(() -> new RuntimeException("文档不存在"));
        return convertToResponse(document);
    }

    /**
     * 删除文档
     */
    @Transactional
    public void deleteDocument(Long userId, Long documentId) {
        UserDocument document = documentRepository.findById(documentId)
                .orElseThrow(() -> new RuntimeException("文档不存在"));

        if (!document.getUserId().equals(userId)) {
            throw new RuntimeException("无权限删除此文档");
        }

        if (document.getAuditStatus() == UserDocument.AuditStatus.APPROVED) {
            throw new RuntimeException("已审核通过的文档不能删除");
        }

        // 删除OSS文件
        ossService.deleteFile(document.getFilePath());

        // 删除记录
        documentRepository.delete(document);
        log.info("文档删除成功，ID: {}", documentId);
    }
    

    /**
     * 验证文件
     */
    private void validateFile(MultipartFile file) {
        if (file.isEmpty()) {
            throw new RuntimeException("文件不能为空");
        }

        if (file.getSize() > maxFileSize) {
            throw new RuntimeException("文件大小超过限制");
        }

        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.isEmpty()) {
            throw new RuntimeException("文件名不能为空");
        }

        // 检查文件类型
        String extension = getFileExtension(originalFilename).toLowerCase();
        if (!isAllowedFileType(extension)) {
            throw new RuntimeException("不支持的文件类型");
        }
    }



    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return "";
        }
        return filename.substring(lastDotIndex + 1);
    }

    /**
     * 检查是否为允许的文件类型
     */
    private boolean isAllowedFileType(String extension) {
        return extension.matches("jpg|jpeg|png|pdf|doc|docx");
    }

    /**
     * 管理员创建文档
     */
    @Transactional
    public DocumentResponse createDocumentByAdmin(Map<String, Object> request) {
        Long userId = Long.valueOf(request.get("userId").toString());
        String documentType = request.get("documentType").toString();
        String filePath = request.get("filePath").toString();
        String fileName = request.get("fileName").toString();
        String remark = request.get("remark") != null ? request.get("remark").toString() : null;

        // 检查用户是否存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        UserDocument document = new UserDocument();
        document.setUserId(userId);
        document.setDocumentType(UserDocument.DocumentType.valueOf(documentType));
        document.setFilePath(filePath);
        document.setDocumentName(fileName); // 使用documentName字段
        document.setAuditStatus(UserDocument.AuditStatus.PENDING);
        document.setCreatedAt(LocalDateTime.now());
        document.setUpdatedAt(LocalDateTime.now());

        UserDocument savedDocument = documentRepository.save(document);
        log.info("管理员创建文档成功: 用户ID={}, 文档类型={}", userId, documentType);
        
        return convertToResponse(savedDocument);
    }

    /**
     * 获取待审核文档列表（管理员专用）
     */
    public List<DocumentResponse> getPendingAuditDocuments() {
        List<UserDocument> documents = documentRepository.findByAuditStatusOrderByCreatedAtAsc(UserDocument.AuditStatus.PENDING);
        return documents.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    /**
     * 批量审核文档（管理员专用）
     */
    @Transactional
    public void batchAuditDocuments(List<Long> documentIds, String auditStatus, String auditComment) {
        for (Long documentId : documentIds) {
            try {
                UserDocument document = documentRepository.findById(documentId)
                        .orElseThrow(() -> new RuntimeException("文档不存在: " + documentId));
                
                document.setAuditStatus(UserDocument.AuditStatus.valueOf(auditStatus));
                document.setAuditComment(auditComment);
                document.setAuditTime(LocalDateTime.now());
                document.setUpdatedAt(LocalDateTime.now());
                
                documentRepository.save(document);
                log.info("批量审核文档成功，文档ID: {}, 状态: {}", documentId, auditStatus);
            } catch (Exception e) {
                log.error("批量审核文档失败，文档ID: {}, 错误: {}", documentId, e.getMessage());
            }
        }
        log.info("批量审核文档完成，处理数量: {}", documentIds.size());
    }

    /**
     * 转换为响应DTO
     */
    private DocumentResponse convertToResponse(UserDocument document) {
        DocumentResponse response = new DocumentResponse();
        response.setId(document.getId());
        response.setUserId(document.getUserId());
        response.setDocumentType(document.getDocumentType());
        response.setDocumentName(document.getDocumentName());
        response.setDescription(document.getDescription());
        response.setDocumentNumber(document.getDocumentNumber());
        response.setFilePath(document.getFilePath());
        response.setFileSize(document.getFileSize());
        response.setAuditStatus(document.getAuditStatus());
        response.setAuditComment(document.getAuditComment());
        response.setAuditUserId(document.getAuditUserId());
        response.setAuditTime(document.getAuditTime());
        response.setCreatedAt(document.getCreatedAt());
        response.setUpdatedAt(document.getUpdatedAt());
        return response;
    }
}
